package config

import (
	"ac-common-go/common"
	config "ac-common-go/config"
	log "ac-common-go/glog"
	"net"
	"reflect"
)

var ConfigInfo *Config

type Config struct {
	Mymap  map[string]interface{}
	strcet string
}

func (this *Config) Load() error {
	this.Mymap = make(map[string]interface{})
	conf, err := config.ReadConfigFile("./conf/privateprotocol.conf")
	if err != nil {
		log.Errorf("read config file failed:err[%v]", err)
		return err
	}
	defer this.Print()

	// section self
	this.Mymap["ServiceEnv"], err = conf.GetString("self", "service_env")
	if err != nil || len(this.Mymap["ServiceEnv"].(string)) <= 0 {
		// set default value as production
		this.Mymap["ServiceEnv"] = "production"
		log.Errorf("get config self service env failed:err[%v]", err)
	}
	this.Mymap["ServiceName"], err = conf.GetString("self", "service_name")
	if err != nil || len(this.Mymap["ServiceName"].(string)) <= 0 {
		log.Errorf("get config self service name failed:err[%v]", err)
		return common.ErrInvalidConf
	}

	this.Mymap["ServiceAddr"], err = conf.GetString("self", "service_addr")
	if err != nil || len(this.Mymap["ServiceAddr"].(string)) <= 0 {
		this.Mymap["ServiceAddr"] = this.getMachineIP()
		if len(this.Mymap["ServiceAddr"].(string)) <= 0 {
			log.Errorf("get config self service addr failed:err[%v]", err)
			return common.ErrInvalidConf
		}
	}
	this.Mymap["ServicePort"], err = conf.GetInt64("self", "service_port")
	if err != nil || this.Mymap["ServicePort"].(int64) <= 1024 {
		log.Errorf("get config self service port failed:err[%v]", err)
		return common.ErrInvalidConf
	}
	//section wgAuth
	this.Mymap["WgauthAddr"], err = conf.GetString("wgauth", "wgauthAddr")
	if err != nil || len(this.Mymap["WgauthAddr"].(string)) <= 0 {
		log.Errorf("get config wgauth service addr failed:err[%v]", err)
		return common.ErrInvalidConf
	}
	//section syspara
	this.Mymap["HeartbeatInterval"], err = conf.GetString("syspara", "heartbeatinterval")
	if err != nil || len(this.Mymap["HeartbeatInterval"].(string)) <= 0 {
		log.Errorf("get config heartbeatinterval failed:err[%v]", err)
		return common.ErrInvalidConf
	}
	this.Mymap["ReportInterval"], err = conf.GetString("syspara", "reportinterval")
	if err != nil || len(this.Mymap["ReportInterval"].(string)) <= 0 {
		log.Errorf("get config reportinterval failed:err[%v]", err)
		return common.ErrInvalidConf
	}
	this.Mymap["RetryInterval"], err = conf.GetString("syspara", "retryinterval")
	if err != nil || len(this.Mymap["RetryInterval"].(string)) <= 0 {
		log.Errorf("get config retryinterval failed:err[%v]", err)
		return common.ErrInvalidConf
	}
	this.Mymap["TimeZone"], err = conf.GetInt64("syspara", "timezone")
	if err != nil {
		log.Errorf("get config timezone failed:err[%v]", err)
		return common.ErrInvalidConf
	}
	//xwj add for private protocol end

	//20240304 add for 7s
	this.Mymap["FetureCode7s"], err = conf.GetString("syspara", "fetureCode7s")
	if err != nil {
		log.Errorf("get config timezone failed:err[%v]", err)
		return common.ErrInvalidConf
	}
	this.Mymap["RKey"], err = conf.GetString("syspara", "rkey")
	if err != nil {
		log.Errorf("get config timezone failed:err[%v]", err)
		return common.ErrInvalidConf
	}

	return nil
}
func (this *Config) Print() {
	log.Infoln("start print the virtual current config")
	this.printConfigItem("self", "service_env", this.Mymap["ServiceEnv"])
	this.printConfigItem("self", "service_name", this.Mymap["ServiceName"])
	this.printConfigItem("self", "service_addr", this.Mymap["ServiceAddr"])
	this.printConfigItem("self", "service_port", this.Mymap["ServicePort"])
	this.printConfigItem("wgauth", "wgauthAddr", this.Mymap["WgauthAddr"])
	this.printConfigItem("syspara", "heartbeatinterval", this.Mymap["HeartbeatInterval"])
	this.printConfigItem("syspara", "reportinterval", this.Mymap["ReportInterval"])
	this.printConfigItem("syspara", "retryinterval", this.Mymap["RetryInterval"])
	this.printConfigItem("syspara", "timezone", this.Mymap["TimeZone"])

	this.printConfigItem("syspara", "fetureCode7s", this.Mymap["FetureCode7s"])
	this.printConfigItem("syspara", "rkey", this.Mymap["RKey"])
	log.Infoln("finish print the virtual current config")
}

func (this *Config) printConfigItem(section, name string, item interface{}) {
	log.Infof("config item info[%s.%s.(%v)]", section, name, reflect.TypeOf(item))
}
func Init() {
	myConfig := new(Config)
	myConfig.Load()
	ConfigInfo = myConfig
}
func GetConfigValue(key string) string {
	defer func() {
		if err := recover(); err != nil {
			log.Errorf("get config value error: %s, %+v", key, err)
		}
	}()
	v, found := ConfigInfo.Mymap[key].(string)
	if !found {
		return ""
	}
	return v
}

func GetConfigValueInt64(key string) (int64, bool) {
	defer func() {
		if err := recover(); err != nil {
			log.Errorf("get config value error: %s, %+v", key, err)
		}
	}()
	v, found := ConfigInfo.Mymap[key].(int64)
	if !found {
		return 0, false
	}
	return v, found
}

func (this *Config) getMachineIP() string {
	netInterfaces, err := net.Interfaces()
	if err != nil {
		log.Errorf("net.Interfaces failed, err:[%v]", err.Error())
		return ""
	}
	for i := 0; i < len(netInterfaces); i++ {
		if (netInterfaces[i].Flags & net.FlagUp) != 0 {
			addrs, _ := netInterfaces[i].Addrs()
			for _, address := range addrs {
				if ipnet, ok := address.(*net.IPNet); ok && !ipnet.IP.IsLoopback() {
					if ipnet.IP.To4() != nil {
						log.Infof("the machine IP is: [%s]", ipnet.IP.String())
						return ipnet.IP.String()
					}
				}
			}
		}
	}
	return ""
}
